from fastapi.security import OAuth2PasswordRequestForm
from fastapi import Body, Depends, HTTPException
from datetime import timedelta

from apps import cruds
from apps.api.v1.login_api import login_router
from apps.schemas.token_schema import Token, TokenOAuth
from apps.utils import create_access_token, verify_password
from apps.utils.enumerate import StateEnum
from core.setting import settings


@login_router.post("/access-token", response_model=TokenOAuth)
async def login_access_token(
        form_data: OAuth2PasswordRequestForm = Depends()
):
    """
    OAuth2 compatible token login_api, get an access token for future requests
    token 认证
    :param form_data:
    :return:
    """
    user = await cruds.user_crud.get_one(account=form_data.username)

    if not user:
        raise HTTPException(status_code=401,
                            detail={'msg': "账号不存在"})

    if not verify_password(plain_password=form_data.password, hashed_password=user.password):
        raise HTTPException(status_code=401,
                            detail={'msg': "密码错误"})

    if not user.state == StateEnum.allow:
        raise HTTPException(status_code=401,
                            detail={'msg': "当前账号不可用，请联系管理员"})

    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    return {
        "access_token": create_access_token(
            data={"user_id": user.id, "password": user.password, "domain": settings.SERVER_HOST},
            expires_delta=access_token_expires
        ),
        "token_type": "bearer",
    }


@login_router.post("/token", response_model=Token, name="登录")
async def login(
        account: str = Body(...),
        password: str = Body(...),

):
    # 查询账号 返回user
    user = await cruds.user_crud.get_one(account=account)

    if not user:
        raise HTTPException(status_code=406,
                            detail={'msg': "账号不存在"})

    # 验证密码
    if not verify_password(plain_password=password, hashed_password=user.password):
        raise HTTPException(status_code=401,
                            detail={'msg': "密码错误"})

    if not user.state == StateEnum.allow:
        raise HTTPException(status_code=401,
                            detail={'msg': "当前账号不可用，请联系管理员"})

    # 生成token
    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)

    return {
        "access_token": create_access_token(
            data={"user_id": user.id, "password": user.password, "domain": settings.SERVER_HOST},
            expires_delta=access_token_expires
        ),
        "token_type": "bearer",
        "name": user.account
    }
